package com.xinrui.sunnyday.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xinrui.sunnyday.constant.MessageConstant;
import com.xinrui.sunnyday.entity.Result;
import com.xinrui.sunnyday.exception.SunnydayException;
import com.xinrui.sunnyday.pojo.Menu;
import com.xinrui.sunnyday.pojo.Permission;
import com.xinrui.sunnyday.pojo.Role;
import com.xinrui.sunnyday.pojo.User;
import com.xinrui.sunnyday.service.UserService;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@ResponseBody
@Controller
@RequestMapping("/userSecurity")
public class UserSecurity implements UserDetailsService {
    @Reference
    private UserService userService;

    /**
     * 给用户授予权限和角色
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//        1.查询数据库拿到当前用户的所有的信息和角色与权限
        User userDb = userService.findByName(username);
//        2.给用户授权角色和权限
//        新建一个List集合存放用户授权信息
        List<GrantedAuthority> authorities = new ArrayList<>();
        SimpleGrantedAuthority authority = null;
//        判断是否有这个用户
        if (null != userDb) {
//            拿到密码
            String password = userDb.getPassword();
//            拿到当前用户的角色
            Set<Role> roles = userDb.getRoles();
//            遍历授予角色
            for (Role role : roles) {
                //            授予角色
                authority = new SimpleGrantedAuthority(role.getKeyword());
                authorities.add(authority);
//                拿到当前角色的权限
                Set<Permission> permissions = role.getPermissions();
                if (null != permissions) {
//                    不为空当前角色有权限添加,则授予权限
//                    遍历授予权限
                    for (Permission permission : permissions) {
                        //        授予权限
                        authority = new SimpleGrantedAuthority(permission.getKeyword());
                        authorities.add(authority);
                    }
                }
            }
//            将用户名密码和角色权限添加
            org.springframework.security.core.userdetails.User userDetails =
                    new org.springframework.security.core.userdetails.User(username, password, authorities);
            return userDetails;
        }
        return null;
    }

    /**
     * 回显当前登录的登录名
     *
     * @return
     */
    @GetMapping("/getLoginUsername")
    public Result getLoginUsername() {
//        1.获取登录的用户的登录信息
        org.springframework.security.core.userdetails.User loginUser =
                (org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        2.拿到用户名
        String username = loginUser.getUsername();
//        3.根据用户名查询此用户的所有信息
        User userDb = userService.findByName(username);
//        4.拿到此用户的所有角色信息
        Set<Role> roles = userDb.getRoles();
        List<Menu> menuList = null;
        for (Role role : roles) {
            //循环角色信息拿到角色的id,因为用集合接的不确定有多少个集合，都遍历了
            Integer id = role.getId();
//            5.根据角色的id来查询菜单信息
            menuList = userService.findByMenuId(id);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("loginUsername", username);
        map.put("menuList", menuList);
        return new Result(true, MessageConstant.GET_USERNAME_SUCCESS, map);
    }
}
